package com.wy.tingshu.service;

import com.wy.tingshu.data_object.UserDO;
import com.wy.tingshu.repository.UserRepo;
import com.wy.tingshu.view_object.UserVO;
import org.mindrot.jbcrypt.BCrypt;

/**
 * @author 美女
 * @date 2022/07/10 16:25
 **/
public class UserService {
    private final UserRepo userRepo=new UserRepo();//仓库对象：调用数据库相关操作-单例。表过程对象一般都是单例处理，直接定义到属性上可以减少对象的创建，相对来说性能好一点
    /*账号注册*/
    public UserVO register(String username, String password) {
        //1.先对密码做"加密"，保证存储的密码不是明文密码【这个加密就是做哈希操作】
        //BCrypt类是别人已经写好的代码，在org包下
        String salt= BCrypt.gensalt();//生成随机数据（盐值—加盐操作）
        password = BCrypt.hashpw(password, salt);//盐值与password做哈希，得到加密后的password


        //2.完成数据库表的insert操作(userRepo:直接访问数据库相关对象（repository仓库层）)
         // userDo：描述从Database（数据库）中直接取出来的对象(DO层)
        UserDO userDO= new UserDO(username,password);//观察userDO对象所在类中的构造方法，通过构造方法将输入的username,password初始化赋值给了userDO对象
        userRepo.insert(userDO);//userRepo就代表对用户表的操作，将userDO中的用户名密码进行插入操作。

        //3.将数据库中直接得到的数据转换为我们需要的表现形式
        return new UserVO(userDO);//观察UserVO的构造方法,将userDO对象的uid和username给到了UserVO的对象中
                                //DO是直接从数据库中取出的对象,VO是给前端展示出去的对象
    }

    //登陆方法
    public UserVO login(String username, String password) {
        //1.先根据用户名从表中查出数据，用UserDO对象接收
        //userRepo.selectOneByUsername(username)会返回一个userDO对象，传给这个对象拿出的所有数据
        UserDO userDO=userRepo.selectOneByUsername(username);
        if(userDO==null){
            //userDO已经为空，说明用户名就有问题
            return null;
        }

        //2.检查密码是否正确（从sql中拿到的值 和 当前登录的输入密码做哈希的值相比）
        //BCrypt.checkpw(plaintext,hash)：plaintext代表我们输入的明文密码，hash指sql中拿到的存储的已经哈希过的密码
//        BCrypt.checkpw(password,userDO.password);
        if( BCrypt.checkpw(password,userDO.password)){
            //进行比较,返回true，代表匹配上了，说明用户输入的密码大概率没有问题
            return new UserVO(userDO);
        }else {
            return null;//密码未匹配成功，用户输入密码一定不对
        }
    }
}
